import { routes } from '_/support'
import { getArray, setToken, removeToken, set } from '_/utils/auth'
import { routeEqual, unPackagePermissions } from "_/utils/tools"
import { getMenus, findRoute, nextRoute, routeHasExist } from './utils'
import settings from "@/settings"
settings.merge({ injections: { identity: data => data } });
// 是否记录路由：浏览器刷新后是否保留记录
settings.merge({ plugins: { remember_route: true } });
// 标签缓存键名
settings.merge({ keys: { label_cache: 'nav-tags' } });
// 注入：返回权限列表
settings.merge({ injections: { permissions: () => [] } });
//
const KET_NAVIGATOR_TAGS = settings.keys.label_cache;
// 获取本地标签列表
const getLocalLabels = () => {
  return getArray(KET_NAVIGATOR_TAGS)
    .filter(p => p && findRoute(routes, p.name || p))
    .map(p => {
      let route;
      if (typeof p === "string") {
        route = findRoute(routes, p);
      } else {
        route = findRoute(routes, p.name);
        route.params = p.params;
        route.query = p.query;
      }
      return route;
    })
}

const state = {
  _sider_collpased: false,
  _breadcrumbs: [],
  _tagNavList: settings.plugins.remember_route ? getLocalLabels() : [],
  _home_route: findRoute(routes, settings.route.index),
  _userData: null,
  _permissions: [],
  _routePowers: []
}

const getters = {
  // 侧边栏状态
  siderCollpased: state => state._sider_collpased,
  // 通过权限过滤的菜单项清单
  menus: () => getMenus(settings.injections.permissions(), routes),
  // 完整菜单项清单
  fullmenus: () => getMenus([], routes),
  // 面包屑
  breadcrumbs: state => state._breadcrumbs,
  // 已打开的页面标签
  labels: state => state._tagNavList,
  // 主页路由名称
  homeName: () => settings.route.index,
  // 用户基本数据
  userData: state => state._userData,
  // 用户权限数据
  permissions: state => state._permissions,
  // 路由权限数据
  routePowers: state => state._routePowers
}

const mutations = {
  SET_SIDER_COLLPASE(state, value) {
    if (value === undefined) {
      state._sider_collpased = !state._sider_collpased;
    } else {
      state._sider_collpased = value;
    }
  },

  /** 处理面包屑路径 */
  SET_BREADCRUMB(state, route) {
    const homeRoute = state._home_route;
    let homeItem = { ...homeRoute, to: homeRoute.path, icon: homeRoute.meta.icon };
    let { matched } = route;
    if (matched.some(item => item.name === homeRoute.name)) {
      state._breadcrumbs = [homeItem]
    } else {
      let res = matched
        .filter(item => item.meta === undefined || !item.meta.hideInBread || !item.meta.hideInMenu);
      state._breadcrumbs = [homeItem, ...res]
    }
  },

  /** 设置标签导航列表 */
  SET_LABELS(state, list) {
    let tagList = [...list];
    if (tagList.length < 2) {
      tagList = [state._home_route];
    }
    // 调整标签顺序
    if (tagList[0] && tagList[0].name !== this.getters.homeName) {
      tagList.shift();
    }
    let homeIndex = tagList.findIndex(item => item.name === this.getters.homeName);
    if (homeIndex > 0) {
      let homeTag = tagList.splice(homeIndex, 1)[0];
      tagList.unshift(homeTag)
    }
    state._tagNavList = tagList;
    const dataToSave = tagList.map(p => {
      const obj = {};
      if (p.query && Object.keys(p.query).length > 0) {
        obj.query = { ...p.query };
      }
      if (p.params && Object.keys(p.params).length > 0) {
        obj.params = { ...p.params };
      }
      if (Object.keys(obj).length > 0) {
        return {
          name: p.name, ...obj
        }
      } else {
        return p.name;
      }
    })
    // 本地存储标签导航列表
    set(KET_NAVIGATOR_TAGS, JSON.stringify(dataToSave))
  },
  /**
   * 设置权限
   * @param {*} state Vuex.Store
   * @param {String[]} permissions 权限清单
   */
  SET_PERMISSION(state, permissions) {
    state._permissions = permissions
  },
  /**
   * 设置用户数据
   * @param {*} state Vuex.Store
   * @param {JSON} data 用户数据
   */
  SET_USER_DATA(state, data = {}) {
    state._userData = settings.injections.identity(data);
  }
}

const actions = {
  /** 跳转至首页 */
  gotoHome(context) {
    context.getters.router.push({ name: settings.route.index });
  },

  /** 展开导航菜单栏 */
  expandSider(context) {
    context.commit('SET_SIDER_COLLPASE', false);
  },

  /** 收起导航菜单栏 */
  collpaseSider(context) {
    context.commit('SET_SIDER_COLLPASE', true);
  },

  /** 切换导航菜单栏 */
  toggleSider(context) {
    context.commit('SET_SIDER_COLLPASE');
  },

  /**
   * 页面跳转
   * @param {object} context State
   * @param {object} route 路由，可以是路由对象或者路由名称字符串
   */
  turnTo(context, route) {
    const BLANK = "_blank";
    let registedRoute = null;
    if (typeof route === "string") {
      if (route.startsWith("http://")) {
        // 在新窗口中打开网页
        window.open(route);
        return;
      } else {
        registedRoute = findRoute(routes, route);
      }
    } else {
      registedRoute = findRoute(routes, route.name) || { name: route.name };
      registedRoute.params = route.params;
      registedRoute.query = route.query;
    }
    if (!routeEqual(registedRoute, context.getters.route)) {
      if (registedRoute.meta && registedRoute.meta.isNewWindow) {
        let routeUrl = context.getters.router.resolve(registedRoute);
        window.open(routeUrl.href, BLANK);
      } else {
        context.getters.router.push(registedRoute);
      }
    }
  },

  /**
   * 关闭页面
   * @param {object} context Vuex.Store
   * @param {object} params 关闭参数
   * @param {object} params.route 路由
   * @param {string} params.type 关闭方式。current=关闭当前页，all=关闭全部页面
   */
  closePage(context, params = {}) {
    const { state, commit, dispatch } = context;
    let route = params.route || this.getters.route;
    let type = params.type || 'current';
    let labels = state._tagNavList;
    switch (type) {
      case "all":
        // 关闭除首页外全部标签 -> 打开首页
        dispatch('turnTo', this.getters.homeName);
        commit('SET_LABELS', []);
        break;
      case "others":
        // 关闭除当前及首页外全部标签
        commit('SET_LABELS', labels.filter(
          item => routeEqual(route, item) || item.name === this.getters.homeName
        ));
        break;
      case "left":
      case "right":
        const index = labels.findIndex(p => routeEqual(p, route));
        if (type === 'left') {
          labels.splice(1, index - 1);
        } else {
          labels.splice(index + 1);
        }
        commit('SET_LABELS', labels);
        dispatch('turnTo', route);
        break;
      case "current":
        if (routeEqual(route, this.getters.route)) {
          // 关闭当前路由
          const __nextRoute = nextRoute(labels, route);
          if (__nextRoute.name) {
            dispatch('turnTo', __nextRoute);
          } else {
            dispatch('turnTo', this.getters.homeName);
          }
        } else {
          // 关闭一个其他路由
        }
        commit('SET_LABELS', labels.filter(
          item => !routeEqual(route, item))
        );
        break;
    }
  },

  /**
   * 验证路由
   */
  validateRoute({ state, commit, dispatch }, route) {
    commit('SET_BREADCRUMB', route);
    // 判断标签列表中是否包含
    // debugger;
    if (!routeHasExist(state._tagNavList, route)) {
      state._tagNavList.push(route);
      commit('SET_LABELS', [...state._tagNavList]);
    }
    // 跳过需要处理权限验证的内容
    if (!route || route.meta.disablePermission) {
      return;
    }
    // 如果当前打开页面不在标签栏中，跳到首页
    if (!state._tagNavList.find(item => item.name === route.name)) {
      dispatch('gotoHome');
    }
  },
  /**
   * 记录用户信息
   * @param {*} state Vuex.Store
   * @param {JSON} loginData 用户数据
   */
  login(state, loginData) {
    setToken(loginData.token);
  },
  /**
   * 清空用户信息
   * @param {*} state Vuex.Store
   * @param {*} query -
   */
  logout({ commit, dispatch }, query) {
    commit('SET_PERMISSION', [])
    commit('SET_USER_DATA', null)
    removeToken();
    dispatch('gotoLogin', query)
  },

  authentication({ getters, commit, dispatch }) {
    return new Promise((resolve, reject) => {
      if (getters.userData && getters.userData.length > 0) {
        resolve()
      } else {
        dispatch('accountValidate', {}).then(response => {
          const { ret, data } = response;
          if (ret === 0) {
            commit(`SET_USER_DATA`, data);
            commit(`SET_PERMISSION`, unPackagePermissions(data.permission))
            resolve()
          } else {
            reject(response);
          }
        }).catch(error => reject(error));
      }
    });
  },
  /**
   * 设置路由权限
   * @param {*} state Vuex.Store
   * @param {*} powers -
   */
  setRoutePowers({ state }, powers) {
    state._routePowers = powers;
  },
  /**
   * 跳转至登录页面
   * @param {*} state Vuex.Store
   * @param {JSON} query 附带参数
   */
  gotoLogin(state, query) {
    this.getters.router.push({ name: settings.route.login, query });
  }
}

export default {
  state,
  mutations,
  getters,
  actions
};
